之前deanya大大發表了一篇文章「利用 JavaScript 快速建立廣告輪播看版」 裡面因為他參考的實作方法中,有一些不是JavaScript常見的寫法,因而引起我的興趣。
當時文章只是談到幾個重點,後來想想乾脆寫個會動的來解釋好了,於是有了這篇分享。
話說回來,這個實作的方式,比起deanya大大的作法,反而不是那麼直接了當,程式碼也變長了,需要理解的JavaScript觀念也變多,所以就deanya大大用作教學的目的來說,也許也不見得適合。
<html lang="en">
<meta charset="UTF-8">
<title>輪播廣告Demo</title>
<h1>輪播廣告</h1>
<div id="ad"></div>
<script>
//將圖片連結和超連結這兩個資料分離出來,方便日後維護與新增
var adData = [{
img: 'http://lh3.ggpht.com/UYX3ro5qLZDMyInieR4avSQsmpDVRlbNId4jpGWNzC3sYBh9Ayz1LAoRJciQGECucWXNb0Fzck4VtDqUvvQpLStCA6z2OlwivM09gELP',
link: 'http://www.google.com/doodles/first-day-of-summer-2013'
}, {
img: 'http://lh6.ggpht.com/-piIYxGNeFjvr5FUYpNQyYTAvDSoqizlbmdkfWCXXkVoLosT3dZ77nl_tujI8_hLiUwY_SbMS4l7FynmTJWSSjH_0uDWwMLF2WGbgfqA',
link: 'http://www.google.com/doodles/50th-anniversary-of-the-i-have-a-dream-speech'
}, {
img: 'http://www.google.com/logos/2010/manuel-de-falla10-hp.gif',
link: 'http://www.google.com/doodles/134th-birthday-of-manuel-de-falla'
}, {
img: 'http://www.google.com/logos/2012/olympics-archery-2012-hp.jpg',
link: 'http://www.google.com/doodles/archery-2012'
}];
//製作一個廣告播放器的物件,adPlaceHolder用來放播放廣告容器的id名稱,adData則是廣告的資料陣列
var AdPlayer = function (adPlaceHolder, adData) {
var currentElm, placeHolder, adList;
placeHolder = document.getElementById(adPlaceHolder);
adList = adData;
//將廣告的資料陣列和廣告的HTML內容結合起來
renderAd();
this.start = function () {
getAd();
setInterval(function () {
hideAd();
getNewAd(); //其實是getAd的別名,用這種命名來增加程式的自我描述性
}, 3000);
};
//產生廣告元素
function renderAd() {
//廣告的HTML內容,做成一個模版,如有需要修改HTML的結構,改這裡,所有的內容就會一起改掉。
var template = '<div id="ad-{{no}}" style="display:none"><a href="{{url}}" rel="nofollow"><img src="{{imgPath}}" border="0" width="335" /></a></div>';
for (var i = 0; i < adList.length; i++) {
var adContent = placeHolder.innerHTML;
var temp = template; //複製一份template的內容,以免蓋掉模版的內容
temp = temp.replace(/{{no}}/, i);
temp = temp.replace(/{{url}}/, adList[i].link);
temp = temp.replace(/{{imgPath}}/, adList[i].img);
adContent += temp;
placeHolder.innerHTML = adContent;
}
}
//亂數播出一個廣告
function getAd() {
var no = getRandomNo();
currentElm = document.getElementById("ad-" + no);
currentElm.style.display = "block";
}
//相同功能,只是增加程式的描述性
var getNewAd = getAd;
//將播過的廣告隱藏起來
function hideAd() {
currentElm.style.display = "none";
}
//亂數號碼產生器
function getRandomNo() {
var size = adList.length;
var no = Math.floor(Math.random() * size);
return no;
}
};
window.onload = function(){
var player = new AdPlayer("ad", adData);
player.start();
}
</script>
改寫的重點有幾個:
(1) 播放器物件化,增加重用性。例如將28~82行的內容存成一隻AdPlayer.js,其他的人想用的時候,只要掛上這隻JS,指定廣告的容器id和廣告的資料,即可使用。
(2) 拆開資料與DOM結構,讓資料歸資料。資料的異動性高,拆出就不用再去碰程式。
(3) 將功能拆小,責任分離,讓程式好維護。例如現在的播放器有一個不夠完美的地方,就是他是亂數播放,因此這次播過的,下次還有可能再播同一個。這個修改的方法,可以透過在 getRandomNo() 裡面,增加不重複播放的方法來給出號碼,這樣就只需要更動這個部分,其他的程式都不會受影響。
(4) 原有的程式每播一次就要合成一次DOM,這個一開始就先把廣告載下,然後透過CSS來切換,兩者相比,後者的效能會比較好。